<template>
  <div v-if="optionsData" class="drawerTemplate-content">
    <n-tabs
      v-if="optionsData.contentType === 'tab'"
      type="segment"
      animated
      class="drawerTemplate-tabs"
      v-model:value="drawerTemplateTabsVal"
      :on-update:value="updateDrawerTemplateTabsValFn"
    >
      <n-tab-pane
        v-for="(item, key) in optionsData.list"
        :name="item.id"
        :key="key"
        :tab="getLabelFn(item)"
      >
        <n-tabs
          v-if="item.type === 'tab' && item.list && item.list.length"
          type="card"
          animated
          class="drawerTemplate-tabs-card"
          v-model:value="drawerTemplateTabsCardVal"
          :on-update:value="updateDrawerTemplateTabsCardValFn"
        >
          <n-tab-pane
            v-for="(lItem, lKey) in item.list"
            :name="lItem.id"
            :key="lKey"
            :tab="getLabelFn(lItem)"
          >
            <DrawerTemplateType ref="drawerTemplateTypeRef" :data="lItem" />
          </n-tab-pane>
        </n-tabs>

        <DrawerTemplateType v-else ref="drawerTemplateTypeRef" :data="item" />
      </n-tab-pane>
    </n-tabs>

    <DrawerTemplateType
      v-else
      ref="drawerTemplateTypeRef"
      :data="optionsData"
    />
  </div>
</template>

<script lang="ts" setup name="DrawerTemplate">
import { useMixins } from '@/hooks/useMixins';

import DrawerTemplateType from './DrawerTemplateType.vue';

// import { dfModBusAllWriteList as newList } from '@/utils/dfModbus/data';

import { cloneDeep } from 'lodash-es';

// import {
//   addChildProcessFn,
//   deleteChildProcessFn
// } from '@/utils/dfModbus/childProcess';

// import { modbusChildOptionsList } from '@main/plc/dataOptions/options';

const modbusChildOptionsList = [];

const addChildProcessFn = (_a,_b) => null;

const deleteChildProcessFn = () => null;

const isUseChildProcess = false;

const dfModBusAllWriteList:any = cloneDeep([]);

const provitGetDfModBusReadListFn: any = inject('provitGetDfModBusReadListFn',null);

const provitSetDfModBusReadListFn: any = inject('provitSetDfModBusReadListFn',null);

const provitGetDfModBusReadListByPlcIdFn: any = inject(
  'provitGetDfModBusReadListByPlcIdFn',null
);

const { language } = useMixins();

const drawerTemplateTypeRef: any = ref(null);

const optionsData: any = ref(null);

const activeId: any = ref(null);

const drawerTemplateTabsVal: any = ref(null);

const drawerTemplateTabsCardVal: any = ref(null);

const loading: any = ref(false);

const lengSelectValue: any = ref(null);

const connectType = inject('connectType',null);

const emit = defineEmits(['scrollToActiveIdFn', 'updateSaveParametersTabFn']);

let addReadList: any = [];

const derangedArray = arr => {
  if (arr && arr.length) {
    const newArr = cloneDeep(arr);

    for (
      let j, x, i = newArr.length;
      i;
      j = parseInt(Math.random() * i),
        x = newArr[--i],
        newArr[i] = newArr[j],
        newArr[j] = x
    );

    return newArr;
  }

  return [];
};

const addReadLengFunIdObjFn = (funIdList, addReadLengFunIdObj) => {
  if (
    funIdList &&
    addReadLengFunIdObj &&
    lengSelectValue &&
    lengSelectValue.value &&
    addReadLengFunIdObj[lengSelectValue.value]
  ) {
    return [...funIdList, ...addReadLengFunIdObj[lengSelectValue.value]];
  }

  return funIdList || [];
};

const addReadFn = async () => {
  // 动态添加funId读取列表
  if (addReadList && addReadList.length) {
    await deleteAddReadListFn();
    console.log('删除');
    // await deleteChildProcessFn();
  }

  // console.log(optionsData.value)

  if (optionsData && optionsData.value) {
    const {
      contentType = null,
      list = [],
      addReadLengFunIdObj = null
    } = optionsData.value;

    const plcAddReadList: any = [];

    let inputList: any = [];

    let funIdList: any = [];

    if (list && list.length) {
      if (contentType === 'tab') {
        // console.log(drawerTemplateTabsVal.value)
        // console.log(toRaw(list))
        if (drawerTemplateTabsVal && drawerTemplateTabsVal.value) {
          toRaw(list).every(item => {
            if (
              item.id === drawerTemplateTabsVal.value &&
              item.list &&
              item.list.length
            ) {
              if (
                drawerTemplateTabsCardVal &&
                drawerTemplateTabsCardVal.value
              ) {
                item.list.every(lItem => {
                  if (
                    lItem.type === 'tab' &&
                    lItem.list &&
                    lItem.list.length &&
                    lItem.id === drawerTemplateTabsCardVal.value
                  ) {
                    inputList = lItem.list;

                    if (item.addReadLengFunIdObj) {
                      funIdList = addReadLengFunIdObjFn(
                        funIdList,
                        lItem.addReadLengFunIdObj
                      );
                    }

                    return false;
                  }

                  return true;
                });
              } else {
                inputList = item.list;

                if (item.addReadLengFunIdObj) {
                  funIdList = addReadLengFunIdObjFn(
                    funIdList,
                    item.addReadLengFunIdObj
                  );

                  // console.log(item.addReadLengFunIdObj)
                }
              }

              return false;
            }

            return true;
          });
        }
      } else {
        inputList = list;
      }
    }

    // console.log(inputList)

    funIdList = [...funIdList, ...findFunIdList(inputList)];

    if (addReadLengFunIdObj) {
      funIdList = addReadLengFunIdObjFn(funIdList, addReadLengFunIdObj);
    }

    if (funIdList && funIdList.length) {
      // console.log(funIdList)

      for (const item of funIdList) {
        let addReadListHasFunId = false;

        if (addReadList && addReadList.length) {
          addReadListHasFunId = !addReadList.every(aItem => {
            const { list: aList = [] } = aItem;

            let hasFunId = false;

            if (aList && aList.length) {
              hasFunId = !aList.every(lItem => {
                const { funId = null } = lItem;

                if (funId && funId === item) {
                  return false;
                }

                return true;
              });
            }

            return !hasFunId;
          });
        }

        if (!addReadListHasFunId) {
          dfModBusAllWriteList.every(dItem => {
            if (dItem.isAdd === false) {
              return true;
            }

            const { list: dList = [] } = dItem;

            let hasFunId = false;

            if (dList && dList.length) {
              hasFunId = !dList.every(lItem => {
                const { funId = null } = lItem;

                if (funId && funId === item) {
                  addReadList.push(dItem);

                  return false;
                }

                return true;
              });
            }

            return !hasFunId;
          });
        }
      }

      if (
        addReadList &&
        addReadList.length &&
        provitGetDfModBusReadListFn &&
        provitGetDfModBusReadListFn.value &&
        provitSetDfModBusReadListFn &&
        provitSetDfModBusReadListFn.value
      ) {
        for (const item of addReadList) {
          item.isAdd = true;

          if (item.list && item.list.length) {
            for (const lItem of item.list) {
              const { code = null } = lItem;

              switch (String(code)) {
                case '10':
                case '6':
                  lItem.code = 3;

                  break;

                case '5':
                case '0F':
                  lItem.code = 1;

                  break;

                default:
                  break;
              }
            }
          }

          if (item.plcId) {
            const obj = plcAddReadList.find(
              pItem => pItem.plcId === item.plcId
            );

            if (obj) {
              obj.list = [...obj.list, item];
            } else {
              plcAddReadList.push({
                plcId: item.plcId,
                list: [item]
              });
            }
          }
        }
      }

      if (plcAddReadList && plcAddReadList.length) {
        const allPlcAdd = false;

        for (const aItem of plcAddReadList) {
          const { plcId = null, list: aList = [] } = aItem;

          if (
            plcId &&
            aList &&
            aList.length &&
            provitGetDfModBusReadListByPlcIdFn &&
            provitGetDfModBusReadListByPlcIdFn.value
          ) {
            let plcList: any = [];

            if (
              isUseChildProcess &&
              modbusChildOptionsList &&
              modbusChildOptionsList.length
            ) {
              plcList =
                modbusChildOptionsList.filter(cItem => cItem.plcId === plcId) ||
                [];

              if (!plcList || !plcList.length) {
                throw new Error(
                  '没有找到plcId为' + plcId + '的modbus子进程配置'
                );
              }
            } else {
              plcList =
                (await provitGetDfModBusReadListByPlcIdFn.value(
                  { plcId },
                  true
                )) || [];
            }

            // console.log(plcList)

            if (plcList && plcList.length) {
              const plcNum = plcList.length;

              const addReadNum = aList.length;

              // console.log(aItem)

              // console.log(plcList)

              if (allPlcAdd) {
                plcList.forEach((dItem, _dKey) => {
                  if (isUseChildProcess) {
                    // console.log(plcList)
                    // console.log(aList[dNum])

                    // addChildProcessFn(dItem, [aList[dNum]])
                    addChildProcessFn(dItem, aList);
                  } else {
                    const { modbusId: pModbusId = null } = dItem;

                    if (pModbusId) {
                      provitSetDfModBusReadListFn.value({
                        modbusId: pModbusId,
                        list: aList
                      });
                    }
                  }

                  // dNum++

                  // if(dNum>addReadNum-1){
                  //   dNum = 0;
                  // }
                });
              } else if (plcNum > addReadNum) {
                // console.log(plcNum)
                // console.log(11)
                let dNum = 0;

                plcList.forEach((dItem, _dKey) => {
                  if (isUseChildProcess) {
                    // console.log(plcList)
                    // console.log(aList[dNum])

                    addChildProcessFn(dItem, [aList[dNum]]);
                    // addChildProcessFn(dItem, aList)
                  } else {
                    const { modbusId: pModbusId = null } = dItem;

                    if (pModbusId) {
                      provitSetDfModBusReadListFn.value({
                        modbusId: pModbusId,
                        list: [aList[dNum]]
                      });

                      // console.log(aList);
                    }
                  }

                  dNum++;

                  if (dNum > addReadNum - 1) {
                    dNum = 0;
                  }
                });
              } else {
                const num = Math.ceil(addReadNum / plcNum);

                let aChildList: any = [];

                aList.forEach(async (item, key) => {
                  const pNum = Math.ceil((key + 1) / num - 1);

                  if (isUseChildProcess) {
                    if (key % num !== 0) {
                      aChildList.push(item);
                    } else {
                      addChildProcessFn(plcList[pNum], aChildList);

                      // console.log(aChildList)

                      aChildList = [];
                    }
                  } else {
                    const { modbusId: pModbusId = null } = plcList[pNum];

                    if (pModbusId) {
                      const list =
                        (await provitGetDfModBusReadListFn.value({
                          modbusId: pModbusId
                        })) || [];

                      list.push(item);

                      provitSetDfModBusReadListFn.value({
                        modbusId: pModbusId,
                        list: derangedArray(list)
                      });

                      // console.log(list)
                    }
                  }

                  if (key === addReadNum - 1) {
                    if (pNum < plcList.length - 1) {
                      for (let i = 0; i < plcList.length; i++) {
                        if (i > pNum) {
                          // console.log(i);
                          if (isUseChildProcess) {
                            addChildProcessFn(plcList[pNum], aList);
                          } else {
                            const { modbusId: pModbusId = null } = plcList[i];

                            if (pModbusId) {
                              const list =
                                (await provitGetDfModBusReadListFn.value({
                                  modbusId: pModbusId
                                })) || [];

                              list.push(item);

                              provitSetDfModBusReadListFn.value({
                                modbusId: pModbusId,
                                list: derangedArray(list)
                              });
                            }
                          }
                        }
                      }
                    }
                  }
                });
              }
            }

            // aList.forEach(async (item, key) => {
            //   const { modbusId = null } = item;

            //   // const options = modbusOptionsList.find((item) => item.plcId === plcId);

            //   // // console.log(modbusOptionsList)

            //   // if (options) {
            //   //   addChildProcessFn(options, [item])
            //   // }
            //   if (plcList && plcList.length) {

            //     // for (const pItem of plcList) {
            //     //   const { modbusId: pModbusId = null } = pItem;

            //     //   if (pModbusId && modbusId!==pModbusId) {
            //     //     const list =
            //     //       (await provitGetDfModBusReadListFn.value({
            //     //         modbusId: pModbusId
            //     //       })) || [];

            //     //     list.push(item);

            //     //     provitSetDfModBusReadListFn.value({
            //     //       modbusId: pModbusId,
            //     //       list:derangedArray(list)
            //     //     });
            //     //   }
            //     // }

            //     console.log(plcList)

            //     if (plcNum > addReadNum) {
            //       for (const pItem of plcList) {
            //         const { modbusId: pModbusId = null } = pItem;

            //         if (pModbusId) {
            //           const list =
            //             (await provitGetDfModBusReadListFn.value({
            //               modbusId: pModbusId
            //             })) || [];

            //           list.push(item);

            //           provitSetDfModBusReadListFn.value({
            //             modbusId: pModbusId,
            //             list: derangedArray(list)
            //           });
            //         }
            //       }
            //     } else {
            //       const num = Math.ceil(addReadNum / plcNum);

            //       const pNum = Math.ceil((key + 1) / num - 1);

            //       const { modbusId: pModbusId = null } = plcList[pNum];

            //       if (pModbusId) {
            //         const list =
            //           (await provitGetDfModBusReadListFn.value({
            //             modbusId: pModbusId
            //           })) || [];

            //         list.push(item);

            //         provitSetDfModBusReadListFn.value({
            //           modbusId: pModbusId,
            //           list: derangedArray(list)
            //         });
            //       }

            //       if (key === addReadNum - 1) {
            //         if (pNum < plcList.length - 1) {
            //           for (let i = 0; i < plcList.length; i++) {
            //             if (i > pNum) {
            //               console.log(i)
            //               const { modbusId: pModbusId = null } = plcList[i];

            //               if (pModbusId) {
            //                 const list =
            //                   (await provitGetDfModBusReadListFn.value({
            //                     modbusId: pModbusId
            //                   })) || [];

            //                 list.push(item);

            //                 provitSetDfModBusReadListFn.value({
            //                   modbusId: pModbusId,
            //                   list: derangedArray(list)
            //                 });
            //               }
            //             }
            //           }
            //         }
            //       }
            //     }

            //   }

            //   if (plcId) {

            //   } else {
            //     const list =
            //       (await provitGetDfModBusReadListFn.value({
            //         modbusId
            //       })) || [];

            //     list.push(item);

            //     provitSetDfModBusReadListFn.value({ modbusId, list });
            //   }
            // })

            // list.every(item)
          }
        }
      }
    }

    console.log(plcAddReadList);

    console.log(addReadList);

    // console.log(funIdList);
  }
};

const updateDrawerTemplateTabsValFn = async val => {
  // 切换tab方法并且更新动态添加读取列表
  if (val) {
    drawerTemplateTabsVal.value = val;

    emit('updateSaveParametersTabFn', val);

    if (
      optionsData.value &&
      optionsData.value.list &&
      optionsData.value.list.length
    ) {
      const isTab = !optionsData.value.list.every(item => {
        const { type = null, list = [], id = null } = item;
        if (id && val === id && type === 'tab') {
          if (drawerTemplateTabsCardVal.value === null && list && list.length) {
            drawerTemplateTabsCardVal.value = list[0].id || null;
          }

          return false;
        }

        return true;
      });

      if (!isTab) {
        drawerTemplateTabsCardVal.value = null;
      }

      if(connectType === 'modbus'){
        await addReadFn();
      }
    }
  }
};

const updateDrawerTemplateTabsCardValFn = async val => {
  // 切换tab中的tab方法并且更新动态添加读取列表
  if (val) {
    drawerTemplateTabsCardVal.value = val;

    if(connectType === 'modbus'){
      await addReadFn();
    }
  }
};

const updateLengSelectValueFn = async val => {
  // 更新楞别值方法并且动态添加楞别的读取列表
  if (val) {
    lengSelectValue.value = val;

    if(connectType === 'modbus'){
      await addReadFn();
    }
  }
};

provide('updateLengSelectValueFn', updateLengSelectValueFn);

provide('lengSelectValue', lengSelectValue);

const chooseItem: any = inject('chooseItem',null);

if (chooseItem && chooseItem.value) {
  const { corrugatedTypeId = null } = chooseItem.value;

  if (corrugatedTypeId) {
    // 当天工单楞别类型
    updateLengSelectValueFn(corrugatedTypeId);
  }
}

const listenScrollFn = e => {
  // 监听滚动事件
  if (
    optionsData.value &&
    optionsData.value.list &&
    optionsData.value.list.length
  ) {
    optionsData.value.list.every(item => {
      if (item.id) {
        const idView: any = document.querySelector(`#${item.id}`);

        if (
          idView.offsetTop + idView.offsetHeight - e.target.offsetHeight / 2 >=
          e.target.scrollTop
        ) {
          activeId.value = item.id;

          return false;
        }
      }

      return true;
    });
  }
};

const getLabelFn = item => {
  if (item) {
    const { labelZh = null, labelEn = null,labelRu=null } = item;

    if (labelZh || labelEn || labelRu) {
      return language.value === 'zh' ? labelZh || labelEn || labelRu : language.value === 'ru' ? labelRu || labelZh || labelEn : labelEn || labelZh || labelRu;
    }
  }
  return '-';
};

const deleteAddReadListFn = async () => {
  // 删除动态添加读取列表的方法
  if (addReadList && addReadList.length) {
    for (const item of addReadList) {
      const { modbusId = null, plcId = null } = item;

      if (
        modbusId &&
        provitGetDfModBusReadListFn &&
        provitGetDfModBusReadListFn.value &&
        provitSetDfModBusReadListFn &&
        provitSetDfModBusReadListFn.value
      ) {
        if (
          plcId &&
          provitGetDfModBusReadListByPlcIdFn &&
          provitGetDfModBusReadListByPlcIdFn.value
        ) {
          const plcList = await provitGetDfModBusReadListByPlcIdFn.value({
            plcId
          });

          // console.log(plcList)

          if (plcList && plcList.length) {
            for (const pItem of plcList) {
              const { modbusId: pModbusId = null } = pItem;

              if (pModbusId) {
                const list =
                  (await provitGetDfModBusReadListFn.value({
                    modbusId: pModbusId
                  })) || [];

                if (list && list.length) {
                  list.forEach((item, key) => {
                    if (item.isAdd) {
                      list.splice(key, 1);
                    }
                  });

                  provitSetDfModBusReadListFn.value({
                    modbusId: pModbusId,
                    list
                  });
                }
              }
            }
          }
        } else {
          const list =
            (await provitGetDfModBusReadListFn.value({ modbusId })) || [];

          if (list && list.length) {
            list.forEach((item, key) => {
              if (item.isAdd) {
                list.splice(key, 1);
              }
            });

            provitSetDfModBusReadListFn.value({ modbusId, list });
          }
        }
      }
    }

    addReadList = [];
  }
};

const findFunIdList = (list: any = []) => {
  // 把页面中的用到的funId都列出来
  let newList: any = [];

  for (const item of list) {
    const { list = [], funId = null, lengFunIdObj = null } = item;

    if (funId) {
      newList.push(item.funId);
    }

    if (
      lengFunIdObj &&
      lengSelectValue &&
      lengSelectValue.value &&
      lengFunIdObj[lengSelectValue.value]
    ) {
      newList.push(lengFunIdObj[lengSelectValue.value]);
    }

    if (list && list.length) {
      newList = [...newList, ...findFunIdList(list)];
    }
  }

  return newList;
};

const setMaterialParamFn: any = inject('setMaterialParamFn',null);

const btnClickFn = fn => {
  // 保存参数
  try {
    if (drawerTemplateTypeRef && drawerTemplateTypeRef.value) {
      const list = drawerTemplateTypeRef.value.length
        ? drawerTemplateTypeRef.value[0].getAllDrawerTemplateInputDataFn()
        : drawerTemplateTypeRef.value.getAllDrawerTemplateInputDataFn();

      console.log(list);

      loading.value = true;

      setMaterialParamFn(list, () => {
        loading.value = false;

        fn && fn();
      });
    }
  } catch (e) {
    loading.value = false;

    fn && fn();

    console.log(e);
  }
};

// const refList: any = [];

// const setRefFn = (el: any, name: any) => {
//   if (el) {
//     const obj = {
//       name,
//       el
//     };

//     const isAdd = refList.every((item, key) => {
//       if (item.name === name) {
//         refList[key] = obj;

//         return false;
//       }

//       return true;
//     });

//     if (isAdd) {
//       refList.push(obj);
//     }
//   }

// };

const removeListenerFn = () => {
  // 移除滚动监听
  const contian: any = document.querySelector('.n-drawer-body-content-wrapper');

  if (contian) {
    contian.removeEventListener('scroll', listenScrollFn);
  }
};

const initFn = (data: any, id = null, scrollId = null) => {
  // 初始化
  const { list = [], contentType = null } = data;

  optionsData.value = cloneDeep(data);

  if (contentType !== 'tab') {
    nextTick(() => {
      const contian: any = document.querySelector(
        '.n-drawer-body-content-wrapper'
      );

      if (id) {
        emit('scrollToActiveIdFn', id, scrollId);
        // scrollToActiveIdFn(id, scrollId);
      } else {
        if (list && list.length && list[0].id) {
          emit('scrollToActiveIdFn', list[0].id);
          // scrollToActiveIdFn(list[0].id);
        } else {
          activeId.value = null;
        }
      }

      if (contian) {
        contian.addEventListener('scroll', listenScrollFn);
      }
    });
  } else {
    if (id) {
      drawerTemplateTabsVal.value = id;

      emit('updateSaveParametersTabFn', id);

      if (scrollId) {
        nextTick(() => {
          drawerTemplateTabsCardVal.value = scrollId;
        });
      } else {
        drawerTemplateTabsCardVal.value = null;
      }
    } else {
      if (list && list.length && list[0].id) {
        drawerTemplateTabsVal.value = list[0].id;

        emit('updateSaveParametersTabFn', list[0].id);
      }
    }
  }

  if(connectType === 'modbus'){
    nextTick(() => {
      addReadFn();
    });
  }


};

defineExpose({
  btnClickFn,
  initFn,
  removeListenerFn,
  deleteAddReadListFn: isUseChildProcess
    ? deleteChildProcessFn
    : deleteAddReadListFn
});
</script>

<style lang="less" scoped>
.drawerTemplate-tabs {
  margin: 16px 0;
  color: #222222;

  :deep(.n-tabs-rail) {
    width: auto;
    margin: 0 auto;
    height: 52px;
    border-radius: 4px;

    .n-tabs-tab-wrapper .n-tabs-tab {
      padding: 12px 36px;
      margin: 4px 6px;
      border-radius: 4px;
      font-size: 20px;
      transition: 0.3s all;
      line-height: normal;

      &.n-tabs-tab--active {
        background-color: #307AFA;
        color: #fff;
        transition: 0.3s all;
      }
    }
  }

  .drawerTemplate-tabs-card {
    margin: 12px 0;

    :deep(.n-tab-pane) {
      padding: 0;
    }

    :deep(.n-tabs-nav--card-type) {
      padding: 0 20px;

      .n-tabs-tab-pad {
        width: 12px;
        border-color: #cecece;
      }

      .n-tabs-tab {
        padding: 14px 40px;
        font-size: 18px;
        line-height: normal;
        background-color: #fff;
        border-color: #cecece;
        transition: 0.3s all;

        &.n-tabs-tab--active {
          background-color: #fff3f0;
          border-color: #307AFA;
          color: #307AFA;
          transition: 0.3s all;
        }
      }

      .n-tabs-pad {
        border-color: #cecece;
      }
    }
  }

  :deep(.drawerTemplateData) {
    // padding: 0;
    .n-button--primary-type {
      min-width: 100px !important;
    }
  }

  :deep(.drawerTemplateData-view-btn) {
    padding: 0 20px;

    .drawerTemplateInput {
      justify-content: start;
      border-bottom: none;

      .n-button--primary-type {
        min-width: 136px !important;
        height: 48px;
        width: auto;
      }
    }
  }

  :deep(.drawerTemplateData-view-item-block) {
    width: 100%;
  }
}
</style>
